﻿using UnityEngine;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

public class UIResourcesStepDowanload : MonoBehaviour 
{
	//所有列表
	//0：进入游戏前必须下载完成的
	//1：开启游戏前必须下载完成的，包含常规UI、当前场景UI、已开启功能（按等级）UI、窗口配置
	//2：其他场景UI
	//3：未开启功能UI
	//4：可动态下载UI
	
	private static UIResourcesStepDowanload instance;
	
	private readonly string fitName = ".uitresource";
	private char[] pathRootStart;

	public List<UIResourceInfo> allList = new List<UIResourceInfo>();		//所有资源列表   
	public string allListPath = "System/UI_allList.xml";
	
	public List<UIResourceInfo> launchList = new List<UIResourceInfo>();	//这个列表交给launcer处理即可
	public string launchListPath = "System/UI_launchList.xml";
	
	public List<UIResourceInfo> playBaseList = new List<UIResourceInfo>();	//进入游戏时加载的基本列表
	public string playBaseListPath = "System/UI_playBaseList.xml";
	
	public List<UIResourceInfo> scenesList = new List<UIResourceInfo>();		//场景相关资源列表
	public string scenesListPath = "System/UI_scenesList.xml";
	
	public List<UIResourceInfo> levelList = new List<UIResourceInfo>();		//等级相关资源
	public string levelListPath = "System/UI_levelList.xml";
	
	public List<UIResourceInfo> asyncList = new List<UIResourceInfo>();		//支持代码动态加载的相关资源
	public string asyncListPath = "System/UI_asyncList.xml";
	
	
	public List<UIResourceInfo> windowList = new List<UIResourceInfo>();	//窗口资源列表
	public string windowListPath = "System/UI_windowList.xml";				
	
	
	public List<UIResourceInfo> playList = new List<UIResourceInfo>();		//进入下一步游戏前需要下载的队列
	public List<UIResourceInfo> waitingList = new List<UIResourceInfo>();	//待加载列表, 包括必须加载的资源和后台预加载资源
	
	public bool inited;													//是否初始化
	public bool isLaunching = true;										//是否正在Lanch
	public DowanLoadState loadState = DowanLoadState.launching;			//自动加载状态
	
	string GameResourcesRootPath = "";
	
	void Awake()
	{
		instance = this;
	}
	
	public static UIResourcesStepDowanload GetInst()
	{
		return instance;
	}

	[ContextMenu("InitPath")]
	public void InitPath()
	{
		GameResourcesRootPath = Directory.GetCurrentDirectory() + "/data/";
		allListPath = GameResourcesRootPath + allListPath;
		launchListPath = GameResourcesRootPath + launchListPath;
		playBaseListPath = GameResourcesRootPath + playBaseListPath;		
		levelListPath = GameResourcesRootPath + levelListPath;
		scenesListPath = GameResourcesRootPath + scenesListPath;
		asyncListPath = GameResourcesRootPath + asyncListPath;
		
		windowListPath = GameResourcesRootPath + windowListPath;
		
		pathRootStart = GameResourcesRootPath.ToCharArray();
	}

	[ContextMenu("RestAllUIResourceInfo")]
	public void RestAllUIResourceInfo()
	{
		allList.Clear();
		
		string[] files = Directory.GetFiles(GameResourcesRootPath + "GameResources/UI/", "*", SearchOption.AllDirectories);
		foreach(string file in files)
		{
			string extension = Path.GetExtension(file);
			if(extension != fitName && extension != ".lua")
				continue;
			
			string localPath = file.TrimStart(pathRootStart).Replace('\\', '/');
//			if(extension != ".lua")
//				localPath += ".zip";
			
			UIResourceInfo info = new UIResourceInfo();
			info.localPath = localPath;
			
			if(info.localPath.StartsWith("GameResources/UI/Dep/Window/"))
				info.type = ResourceType.Launcher;
			else if(info.localPath.EndsWith(".lua"))
				info.type = ResourceType.Launcher;
			
			allList.Add(info);
		}
		
		XML<UIResourceInfo>.SaveListAtPath(allList, allListPath);
	}
	
	[ContextMenu("UpdateAllUIResourceInfo")]
	public void UpdateAllUIResourceInfo()
	{
		allList.Clear();
		
		List<UIResourceInfo> oldAlllist = XML<UIResourceInfo>.LoadListFromPath(allListPath);
		
		for(int i = 0; i < oldAlllist.Count;)
		{
			string file = GameResourcesRootPath + oldAlllist[i].localPath;
			if(file.EndsWith(".zip"))
				file = file.Substring(0, file.Length - 4);
			if(!File.Exists(file))
				oldAlllist.RemoveAt(i);
			else
				i++;
		}
		
		string[] files = Directory.GetFiles(GameResourcesRootPath + "GameResources/UI/", "*", SearchOption.AllDirectories);
		foreach(string file in files)
		{
			//屏蔽掉打包资源和其他无用资源
			string extension = Path.GetExtension(file);
			if(extension != fitName && extension != ".lua")
				continue;
			
			string localPath = file.TrimStart(pathRootStart).Replace('\\', '/');
//			if(extension != ".lua")
//				localPath += ".zip";
			
			UIResourceInfo info = null;
			foreach(UIResourceInfo oldInfo in oldAlllist)
			{
				if(oldInfo.localPath == localPath)
				{
					info = oldInfo;
					break;
				}
			}			
			
			if(info == null)
			{
				info = new UIResourceInfo();
				info.localPath = localPath;
			}
			
			//窗口配置和lua文件都作为必须加载的文件
			if(info.localPath.StartsWith("GameResources/UI/Dep/Window/"))
			{
				info.type = ResourceType.Launcher;
				info.setOK = true;
			}
			//自动识别地图编号
			else if(info.localPath.StartsWith("GameResources/UI/Base/Material/Map/"))
			{
				int index1 = info.localPath.LastIndexOf('-');
				int index2 = info.localPath.IndexOf('.');
				int mapID = 0;
				if(int.TryParse(info.localPath.Substring(index1 + 1, index2 - index1 - 1), out mapID))
				{
					info.type = ResourceType.Scene;
					info.sceneID = mapID;
					info.setOK = true;
				}
			}
			else if(info.localPath.EndsWith(".lua"))
			{
				info.type = ResourceType.Launcher;
				info.setOK = true;
			}
			
			if(info.type == ResourceType.Launcher && !info.setOK)
				info.type = ResourceType.PlayGame;
			
			allList.Add(info);
		}
		
		XML<UIResourceInfo>.SaveListAtPath(allList, allListPath);
	}
	
	[ContextMenu("UpdateXMLs")]
	public void UpdateXMLs()
	{		
		allList = XML<UIResourceInfo>.LoadListFromPath(allListPath);
		launchList.Clear();
		playBaseList.Clear();
		levelList.Clear();
		scenesList.Clear();
		asyncList.Clear();
		
		windowList.Clear();
			
		for(int i = 0; i < allList.Count;)
		{
			UIResourceInfo info = allList[i];
			
			string file = info.localPath;
			if(file.EndsWith(".zip"))
				file = file.Substring(0, file.Length - 4);
			file = GameResourcesRootPath + file;
			if(!File.Exists(file))
			{
				allList.RemoveAt(i);
				continue;
			}
			else
			{
				i++;
			}
				
			//窗口配置和lua文件都作为必须加载的文件
			if(info.localPath.StartsWith("GameResources/UI/Dep/Window/"))
			{
				info.type = ResourceType.Launcher;
				info.setOK = true;
				
				windowList.Add(info);
			}
			//自动识别地图编号
			else if(info.localPath.StartsWith("GameResources/UI/Base/Material/Map/"))
			{
				int index1 = info.localPath.LastIndexOf('-');
				int index2 = info.localPath.IndexOf('.');
				int mapID = 0;
				if(int.TryParse(info.localPath.Substring(index1 + 1, index2 - index1 - 1), out mapID))
				{
					info.type = ResourceType.Scene;
					info.sceneID = mapID;
					info.setOK = true;
				}
			}
			else if(info.localPath.EndsWith(".lua"))
			{
				info.type = ResourceType.Launcher;
				info.setOK = true;
			}
			
			//没设置的默认添加到launcher下载列表
			if(info.setOK)
			{
				if(info.type == ResourceType.Launcher)
					launchList.Add(info);
				else if(info.type == ResourceType.PlayGame)
					playBaseList.Add(info);
				else if(info.type == ResourceType.Level)
					levelList.Add(info);
				else if(info.type == ResourceType.Scene)
					scenesList.Add(info);
				//未定义的其他文件都作为支持动态加载的文件
				else
					asyncList.Add(info);
			}
			else
			{
				info.type = ResourceType.Async;
				asyncList.Add(info);
//				playBaseList.Add(info);
			}
		}
		
		XML<UIResourceInfo>.SaveListAtPath(allList, allListPath);
		XML<UIResourceInfo>.SaveListAtPath(launchList, launchListPath);
		XML<UIResourceInfo>.SaveListAtPath(playBaseList, playBaseListPath);
		XML<UIResourceInfo>.SaveListAtPath(levelList, levelListPath);
		XML<UIResourceInfo>.SaveListAtPath(scenesList, scenesListPath);
		XML<UIResourceInfo>.SaveListAtPath(asyncList, asyncListPath);
	
		XML<UIResourceInfo>.SaveListAtPath(windowList, windowListPath);
	}
	
	[ContextMenu("更新所有配置")]
	public void UpdateAllXMLs()
	{
		InitPath();
		UpdateAllUIResourceInfo();
		UpdateXMLs();
	}
	
	public static void UpdateUIXMLS()
	{
		if(instance == null)
		{
			GameObject obj = new GameObject("UIResourcesStepDowanload");
			instance = obj.AddComponent<UIResourcesStepDowanload>();
			instance.UpdateAllXMLs();
			DestroyImmediate(obj);
		}
	}
}

public class UIResourceInfo
{
	[XmlAttribute]
	public bool setOK;										//是否处理完
	[XmlAttribute]
	public ResourceType type = ResourceType.Async;		//加载策略类型
	[XmlAttribute]
	public int level;				//开启等级
	[XmlAttribute]
	public int sceneID;				//绑定场景
	[XmlAttribute]
	public int Priority;			//优先级别，越小优先级越高
	[XmlAttribute]
	public string localPath;		//本地相对路径
	
	[XmlIgnore]
	public bool isdownloading;		//是否正在被下载
}

public enum ResourceType
{
	Launcher = 0,						//属于必须在Lancher结束前下载完成的，等待情况：一直lauching
	PlayGame = 1,						//属于必须在开始玩游戏前下载完成的，等待情况：一直loading,该项需要后两项一起完成
	Level = 2,							//属于必须在开启对应等级功能前下载完成的，等待情况：开始游戏前，进入游戏时一直loading；游戏中开启：暂时不允许，应该提前如2等级后台下载资源
	Scene = 3,							//属于必须在进入某场景前下载完成的，等待情况：一直loading
	Async = 4,							//属于支持动态异步加载的资源，如大背景、特效等，等待情况：后台加载
}

public enum DowanLoadState
{
	launching,							//正在Lanch阶段，程序中用不到
	Logining,							//登录至游戏前
	SceneLoading,						//跳转场景，游戏中的跳转
	LevelUping,							//升级
	NormalPlaying,						//常规状态
}